<!--  -->
<template>
  <div class="approval-form">
    <div class="approval-form__content approval-form__box">
      <div class="approval-form__content__header">
        <div>审批流程设置</div>
        <div>
          <el-button v-if="step" @click="goBack">上一步</el-button>
          <el-button @click="goApproval">取消</el-button>
          <el-button @click="onSave" :disabled="['PREVIEW'].includes(query.status)">保存</el-button>
          <el-button
            @click="validateProcess"
            :disabled="['PREVIEW'].includes(query.status)"
            type="primary"
            >发布</el-button
          >
        </div>
      </div>
      <el-steps align-center :active="step" finish-status="success">
        <el-step title="流程信息配置"></el-step>
        <el-step title="审批流程配置"></el-step>
      </el-steps>
      <div v-show="[0].includes(step)">
        <div class="approval-form__container">
          <div class="approval-form__content__title">流程基本信息</div>
          <el-form
            :validate-on-rule-change="false"
            :rules="{
              formName: [{ required: true, message: '请输入流程名称', trigger: 'blur' }]
            }"
            :model="form"
            ref="form"
            label-width="100px"
          >
            <el-form-item label="流程名称" prop="formName">
              <el-input
                :value="form.formName"
                @input="changeFormName"
                maxlength="30"
                show-word-limit
                :disabled="['PREVIEW'].includes(query.status)"
              ></el-input>
            </el-form-item>
            <el-form-item v-if="form.processNo" label="流程编码">
              <el-input disabled :value="`${form.processNo || ''}`"></el-input>
            </el-form-item>
            <el-form-item label="流程类型">
              <el-input disabled :value="`${query.groupName}`"></el-input>
            </el-form-item>
            <el-form-item label="创建人">
              <el-input disabled v-model="form.createName"></el-input>
            </el-form-item>
            <el-form-item label="备注">
              <el-input
                type="textarea"
                :rows="5"
                v-model="form.remark"
                maxlength="100"
                show-word-limit
                :disabled="['PREVIEW'].includes(query.status)"
              ></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="onSubmit">下一步</el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <div :style="[1].includes(step) ? 'opacity:1' : 'opacity:0'">
        <div class="approval-form__content__tree">
          <div class="approval-form__content__tree__scale">
            <el-button
              icon="el-icon-plus"
              size="small"
              @click="scale += 10"
              :disabled="scale >= 150"
              circle
            ></el-button>
            <span>{{ scale }}%</span>
            <el-button
              icon="el-icon-minus"
              size="small"
              @click="scale -= 10"
              :disabled="scale <= 40"
              circle
            ></el-button>
          </div>
          <div
            class="approval-form__content__tree__design"
            :style="'transform: scale(' + scale / 100 + ');'"
          >
            <process-tree id="process-tree" ref="process-tree" @selectedNode="nodeSelected" />
          </div>
          <el-drawer
            :title="selectedNode.name"
            :visible.sync="showConfig"
            :modal-append-to-body="false"
            :size="selectedNode.type === 'CONDITION' ? '600px' : '500px'"
            direction="rtl"
            :modal="false"
            destroy-on-close
          >
            <div slot="title">
              <el-input
                v-model="selectedNode.name"
                size="medium"
                v-show="showInput"
                style="width: 300px"
                maxlength="50"
                @blur="showInput = false"
              ></el-input>
              <el-link v-show="!showInput" @click="() => {
                if (!['PREVIEW'].includes(query.status)) {showInput = true}
              }" style="font-size: medium">
                <i class="el-icon-edit" style="margin-right: 10px"></i>
                {{ selectedNode.name }}
              </el-link>
            </div>
            <div class="node-config-content">
              <div
            class="approval-form__content__disable"
            v-if="['PREVIEW'].includes(query.status)"
          ></div>
              <node-config />
            </div>
          </el-drawer>
        </div>
      </div>
    </div>
    <!-- 校验工具 -->
    <w-dialog :showFooter="false" v-model="validVisible" title="设置项检查">
      <el-steps align-center :active="validStep" finish-status="success">
        <el-step
          v-for="(step, i) in validOptions"
          :title="step.title"
          :key="i"
          :icon="step.icon"
          :status="step.status"
          :description="step.description"
        />
      </el-steps>
      <el-result :icon="validIcon" :title="errTitle()" :subTitle="validResult.desc">
        <i
          slot="icon"
          style="font-size: 30px"
          v-if="!validResult.finished"
          class="el-icon-loading"
        ></i>
        <div slot="subTitle" class="err-info" v-if="validResult.errs.length > 0">
          <ellipsis hover-tip v-for="(err, i) in validResult.errs" :key="i + '_err'" :content="err">
            <i slot="pre" class="el-icon-warning-outline"></i>
          </ellipsis>
        </div>
        <template slot="extra">
          <el-button type="primary" v-if="validResult.finished" size="medium" @click="goFix">
            {{ validResult.action }}
          </el-button>
        </template>
      </el-result>
    </w-dialog>
  </div>
</template>

<script>
import html2canvas from 'html2canvas'
import ProcessTree from '@/views/approval/process/ProcessTree.vue'
import NodeConfig from '@/views/approval/process/common/process/config/NodeConfig.vue'
import { saveProcess, deployProcess, previewProcess, uploadFile } from '@/api/approval.js'
import { getDentify } from '@/utils/auth'
// import { findSealTypeList } from '@/api/signatureManage.js'
export default {
  name: 'ApprovalForm',
  components: { ProcessTree, NodeConfig },
  computed: {
    selectedNode() {
      return this.$store.state.select.selectedNode
    }
  },
  data() {
    return {
      step: 0,
      scale: 100,
      query: {},
      showConfig: false,
      showInput: false,
      data: [],
      userLoginDto: {},
      form: {
        formId: null,
        processNo: null,
        formName: '',
        remark: '',
        createName:''
      },
      // 以下变量为校验工具所需变量
      timer: null,
      validVisible: false,
      validResult: {},
      validStep: 0,
      validOptions: [
        { title: '流程信息配置', description: '', icon: '', status: '' },
        { title: '审批流程配置', description: '', icon: '', status: '' }
      ],
      validComponents: ['form']
    }
  },
  methods: {
    nodeSelected(node) {
      console.log('配置节点', node)
      this.showConfig = true
    },
    onSubmit() {
      this.$refs['form'].validate((valid)=>{
        if(valid){
          this.step = 1
        }
      })
    },
    goBack() {
      this.step = 0
    },
    goApproval() {
      this.$router.push({ path: '/approval/approval' })
    },
    onPublish() {
      this.$confirm('如果您只想临时保存请选择保存，确认发布后流程立即生效，是否继续?', '提示', {
        confirmButtonText: '发布',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        this.validVisible = false
        await this.onSave()
        const { data } = await deployProcess({
          data: {
            formId: this.form.formId
          },
          headers: {}
        })
        if (['部署流程成功'].includes(data)) {
          this.$confirm('发布成功，您想继续留在本页还是返回表单列表呢', '操作成功', {
            confirmButtonText: '留在本页',
            cancelButtonText: '返回列表',
            type: 'success'
          })
            .then(() => {
              window.location.reload()
            })
            .catch(() => {
              this.goApproval()
            })
        } else {
          this.$err(data, '部署流程失败')
        }
      })
    },
    dataURItoBlob(dataURI) {
      // base64转buffer
      var byteString = atob(dataURI.split(',')[1])
      var mimeString = dataURI
        .split(',')[0]
        .split(':')[1]
        .split(';')[0]
      var ab = new ArrayBuffer(byteString.length)
      var ia = new Uint8Array(ab)
      for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i)
      }
      return new Blob([ab], { type: mimeString })
    },
    changeFormName(value) {
      if (/^(?:[a-zA-Z0-9\u4e00-\u9fa5]+)?$/.test(value)) {
        this.form.formName = value
      }
      
    },
    async onSave() {
      this.valids = this.formValidate()
      if (Array.isArray(this.valids) && this.valids.length === 0) {
        const canvas = await html2canvas(document.querySelector('.approval-form__content__tree'), {
          scale: 1
        })
        let form = new FormData()
        form.append('fileType', 0)
        form.append('channelNo', 'anysign')
        form.append('storeType', '1')
        form.append('businessType', '0')
        form.append('expireTag', '0')
        form.append('file', this.dataURItoBlob(canvas.toDataURL('images/jpg')), Date.now() + '.jpg')
        const {
          data: fileData
        } = await uploadFile({
          data: form,
          headers: {
            'Content-type': 'multipart/form-data'
          }
        })
        const object = {
            // orgId: getDentify().orgId,
            filePath: fileData,
            process: JSON.stringify(this.$store.state.select.design.process),
            // createName: getDentify().userName,
            ...this.query,
            ...this.form
          }
          delete object.status
        const { data, msg } = await saveProcess({
          data: object,
          headers: {}
        })
        if (['流程名称重复'].includes(msg)) {
          this.$message.warning(String(data))
          throw data
        } else {
          this.$message.success('保存成功')
          this.form.formId = data ? data.formId : null
          this.form.processNo = data ? data.processNo : null
          return data
        }
      } else {
        this.$message.warning(String(this.valids))
        throw this.valids
      }
    },
    // 以下方法为校验工具所需方法
    validateProcess() {
      this.validVisible = true
      this.validStep = 0
      this.initValiding()
      this.stopTimer()
      this.timer = setInterval(() => {
        this.validResult.errs =
          this.validStep === 0 ? this.formValidate() : this.$refs['process-tree'].validateProcess()
        if (Array.isArray(this.validResult.errs) && this.validResult.errs.length === 0) {
          this.validStep++
          if (this.validStep >= this.validOptions.length) {
            this.stopTimer()
            this.showValidFinish(true)
          }
        } else {
          this.stopTimer()
          this.validOptions[this.validStep].status = 'error'
          this.showValidFinish(false, this.getDefaultValidErr())
        }
      }, 300)
    },
    formValidate() {
      this.$refs.form.validate()
      let err = []
      if (!this.$isNotEmpty(this.form.formName)) {
        err.push('流程名称未设置')
      }
      return err
    },
    stopTimer() {
      if (this.timer) {
        clearInterval(this.timer)
      }
    },
    errTitle() {
      if (this.validResult.finished && !this.validResult.success) {
        return this.validResult.title + ` (${this.validResult.errs.length}项错误) 😥`
      }
      return this.validResult.title
    },
    goFix() {
      if (this.validResult.success) {
        this.onPublish()
      } else {
        this.step = this.validStep
        this.validVisible = false
      }
    },
    getDefaultValidErr() {
      switch (this.validStep) {
        case 0:
          return '请检查基础设置项'
        case 1:
          return '请检查审批流程，查看对应标注节点错误信息'
        default:
          return '未知错误'
      }
    },
    showValidFinish(success, err) {
      this.validResult.success = success
      this.validResult.finished = true
      this.validResult.title = success ? '校验完成 😀' : '校验失败 '
      this.validResult.desc = success ? '设置项校验成功，是否提交？' : err
      this.validResult.action = success ? '提 交' : '去修改'
    },
    errTitle() {
      if (this.validResult.finished && !this.validResult.success) {
        return this.validResult.title + ` (${this.validResult.errs.length}项错误) 😥`
      }
      return this.validResult.title
    },
    validIcon() {
      if (!this.validResult.finished) {
        return 'el-icon-loading'
      } else if (this.validResult.success) {
        return 'success'
      } else {
        return 'warning'
      }
    },
    initValiding() {
      this.validResult = {
        errs: [],
        finished: false,
        success: false,
        title: '检查中...',
        action: '处理',
        desc: '正在检查设置项'
      }
      this.validStep = 0
      this.validOptions.forEach((op) => {
        op.status = ''
        op.icon = ''
        op.description = ''
      })
    },
    loadForm({ process }) {
      this.$store.commit('loadForm', {
        formId: null,
        processNo: null,
        formName: '未命名表单',
        groupId: undefined,
        formItems: [],
        formConfig: {
          labelPos: 'top',
          ruleType: 'SIMPLE',
          labelWidth: '',
          rules: [],
          ruleJs:
            '//formData: 表单数据  formMap: 表单字段id -> 字段json配置\r\nfunction doChange(formData, formMap){\r\n\t\r\n}'
        },
        process:
          this.query.formId && process
            ? JSON.parse(process)
            : {
                id: 'root',
                parentId: null,
                type: 'ROOT',
                name: '发起人',
                desc: '任何人',
                props: {
                  assignedUser: [],
                  formPerms: []
                },
                children: {}
              }
      })
    }
  },
  async created() {
    this.query = this.$route.query
    this.userLoginDto = {
      userName: this.$store.getters.nickname
    }
    this.initValiding()
  },

  async mounted() {
    // const { data } = await findSealTypeList({})

    this.data = [
      {
        id: 1,
        label: '流程分类',
        children: [
          {
            id: 3,
            label: '默认分组',
            children: [
              {
                label: '印章制作'
              },
              {
                label: '业务模版发起'
              }
            ]
          }
        ]
      }
    ]
    this.form.createName = this.userLoginDto.userName
    if (this.query.formId) {
      const { data } = await previewProcess({
        data: {
          formId: this.query.formId
        },
        headers: {}
      })
      console.log(data)
      this.form = {
        formId: this.query.formId,
        processNo: data.processNo,
        formName: data.formName,
        remark: data.remark,
        createName:data.createName
      }
      this.loadForm({ process: data.process })
    } else {
      this.loadForm({})
    }
  }
}
</script>
<style lang="less">
@import './styles/form.less';
</style>
